﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Cryptography;
using System.Text;

namespace WCF
{
    /// <summary>
    /// A class that cryptates the cardnumber stored in the database, using the principle 
    /// of salted hash, which means that the password is first salted with a random value
    /// and then hashed. In the database we then store the hash and the salt, and it is very hard
    /// for someone to decrypt the cardnumbers
    /// </summary>
    public class CardSalt
    {
        private string _cardnumber;
        private int _salt;

        public CardSalt(string cardNumber, int nSalt)
         {
             _cardnumber = cardNumber;
             _salt = nSalt;
         }

        /// <summary>
        /// This method creates the salt
        /// </summary>
        /// <returns>An int with the random salt</returns>
        public static int CreateRandomSalt()
         {
          Byte[] _saltBytes = new Byte[4];
          RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
          rng.GetBytes(_saltBytes);

          return ((((int)_saltBytes[0]) << 24) + (((int)_saltBytes[1]) << 16) + 
             (((int)_saltBytes[2]) << 8) + ((int)_saltBytes[3]));
         }

        /// <summary>
        /// Hash the salted value using the SHA1 algorithm
        /// </summary>
        /// <returns>Hashed value as a string </returns>
        public string ComputeSaltedHash()
        {
            // Create Byte array of password string
            ASCIIEncoding encoder = new ASCIIEncoding();
            Byte[] _secretBytes = encoder.GetBytes(_cardnumber);

            // Create a new salt
            Byte[] _saltBytes = new Byte[4];
            _saltBytes[0] = (byte)(_salt >> 24);
            _saltBytes[1] = (byte)(_salt >> 16);
            _saltBytes[2] = (byte)(_salt >> 8);
            _saltBytes[3] = (byte)(_salt);

            // append the two arrays
            Byte[] toHash = new Byte[_secretBytes.Length + _saltBytes.Length];
            Array.Copy(_secretBytes, 0, toHash, 0, _secretBytes.Length);
            Array.Copy(_saltBytes, 0, toHash, _secretBytes.Length, _saltBytes.Length);

            SHA1 sha1 = SHA1.Create();
            Byte[] computedHash = sha1.ComputeHash(toHash);

            return encoder.GetString(computedHash);
        }
    }
}